Micron Document
🎖️GitЯра🎖️


Displaying Raw • Download

feature/node/src/commonTest/kotlin/org/meshtastic/feature/node/metrics/MetricsViewModelTest.kt a6057f594dee69b0cbfbe7ce662a7d4d53c62f65 (a6057f59) Text, 16.22 KB

T8b949e/*
* Copyright (c) 2026 Meshtastic LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
Tff7b72package T7ee787org.meshtastic.feature.node.metrics

Tff7b72import T7ee787app.cash.turbine.test
Tff7b72import T7ee787dev.mokkery.answering.calls
Tff7b72import T7ee787dev.mokkery.answering.returns
Tff7b72import T7ee787dev.mokkery.every
Tff7b72import T7ee787dev.mokkery.everySuspend
Tff7b72import T7ee787dev.mokkery.matcher.any
Tff7b72import T7ee787dev.mokkery.mock
Tff7b72import T7ee787dev.mokkery.verifySuspend
Tff7b72import T7ee787kotlinx.coroutines.Dispatchers
Tff7b72import T7ee787kotlinx.coroutines.flow.MutableStateFlow
Tff7b72import T7ee787kotlinx.coroutines.flow.asStateFlow
Tff7b72import T7ee787kotlinx.coroutines.flow.flowOf
Tff7b72import T7ee787kotlinx.coroutines.test.StandardTestDispatcher
Tff7b72import T7ee787kotlinx.coroutines.test.resetMain
Tff7b72import T7ee787kotlinx.coroutines.test.runCurrent
Tff7b72import T7ee787kotlinx.coroutines.test.runTest
Tff7b72import T7ee787kotlinx.coroutines.test.setMain
Tff7b72import T7ee787okio.Buffer
Tff7b72import T7ee787okio.BufferedSink
Tff7b72import T7ee787org.meshtastic.core.common.util.CommonUri
Tff7b72import T7ee787org.meshtastic.core.di.CoroutineDispatchers
Tff7b72import T7ee787org.meshtastic.core.repository.FileService
Tff7b72import T7ee787org.meshtastic.core.repository.MeshLogRepository
Tff7b72import T7ee787org.meshtastic.core.repository.NodeRepository
Tff7b72import T7ee787org.meshtastic.core.repository.ServiceRepository
Tff7b72import T7ee787org.meshtastic.core.repository.TracerouteSnapshotRepository
Tff7b72import T7ee787org.meshtastic.feature.node.detail.NodeDetailUiState
Tff7b72import T7ee787org.meshtastic.feature.node.detail.NodeRequestActions
Tff7b72import T7ee787org.meshtastic.feature.node.domain.usecase.GetNodeDetailsUseCase
Tff7b72import T7ee787org.meshtastic.feature.node.model.MetricsState
Tff7b72import T7ee787org.meshtastic.feature.node.model.TimeFrame
Tff7b72import T7ee787org.meshtastic.proto.DeviceMetrics
Tff7b72import T7ee787org.meshtastic.proto.EnvironmentMetrics
Tff7b72import T7ee787org.meshtastic.proto.MeshPacket
Tff7b72import T7ee787org.meshtastic.proto.Position
Tff7b72import T7ee787org.meshtastic.proto.PowerMetrics
Tff7b72import T7ee787org.meshtastic.proto.Telemetry
Tff7b72import T7ee787kotlin.test.AfterTest
Tff7b72import T7ee787kotlin.test.BeforeTest
Tff7b72import T7ee787kotlin.test.Test
Tff7b72import T7ee787kotlin.test.assertEquals
Tff7b72import T7ee787kotlin.test.assertNotNull
Tff7b72import T7ee787kotlin.test.assertTrue

Tff7b72class T56d364MetricsViewModelTest Tb4b4b4{

Tff7b72private Tff7b72val Te6edf3testDispatcher Tff7b72= Te6edf3StandardTestDispatcherTb4b4b4(Tb4b4b4)
Tff7b72private Tff7b72val Te6edf3dispatchers Tff7b72= Te6edf3CoroutineDispatchersTb4b4b4(Te6edf3main Tff7b72= Te6edf3testDispatcherTb4b4b4, Te6edf3io Tff7b72= Te6edf3testDispatcherTb4b4b4, Te6edf3default Tff7b72= Te6edf3testDispatcherTb4b4b4)

Tff7b72private Tff7b72val Te6edf3meshLogRepositoryTb4b4b4: Te6edf3MeshLogRepository Tff7b72= Te6edf3mockTb4b4b4(Tb4b4b4)
Tff7b72private Tff7b72val Te6edf3serviceRepositoryTb4b4b4: Te6edf3ServiceRepository Tff7b72= Te6edf3mockTb4b4b4(Tb4b4b4)
Tff7b72private Tff7b72val Te6edf3nodeRepositoryTb4b4b4: Te6edf3NodeRepository Tff7b72= Te6edf3mockTb4b4b4(Tb4b4b4)
Tff7b72private Tff7b72val Te6edf3tracerouteSnapshotRepositoryTb4b4b4: Te6edf3TracerouteSnapshotRepository Tff7b72= Te6edf3mockTb4b4b4(Tb4b4b4)
Tff7b72private Tff7b72val Te6edf3nodeRequestActionsTb4b4b4: Te6edf3NodeRequestActions Tff7b72= Te6edf3mockTb4b4b4(Tb4b4b4)
Tff7b72private Tff7b72val Te6edf3alertManagerTb4b4b4: Te6edf3orgTb4b4b4.Te6edf3meshtasticTb4b4b4.Te6edf3coreTb4b4b4.Te6edf3uiTb4b4b4.Te6edf3utilTb4b4b4.Te6edf3AlertManager Tff7b72= Te6edf3mockTb4b4b4(Tb4b4b4)
Tff7b72private Tff7b72val Te6edf3getNodeDetailsUseCaseTb4b4b4: Te6edf3GetNodeDetailsUseCase Tff7b72= Te6edf3mockTb4b4b4(Tb4b4b4)
Tff7b72private Tff7b72val Te6edf3fileServiceTb4b4b4: Te6edf3FileService Tff7b72= Te6edf3mockTb4b4b4(Tb4b4b4)

Tff7b72private Tff7b72lateinit Tff7b72var Te6edf3viewModelTb4b4b4: Te6edf3MetricsViewModel

Tf0883e@BeforeTest
Tff7b72fun Td2a8ffsetUpTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3DispatchersTb4b4b4.Te6edf3setMainTb4b4b4(Te6edf3testDispatcherTb4b4b4)

T8b949e// Default setup for flows
Te6edf3every Tb4b4b4{ Te6edf3serviceRepositoryTb4b4b4.Te6edf3tracerouteResponse Tb4b4b4} Te6edf3returns Te6edf3MutableStateFlowTb4b4b4(Tff7b72nullTb4b4b4)
Te6edf3every Tb4b4b4{ Te6edf3nodeRequestActionsTb4b4b4.Te6edf3lastTracerouteTime Tb4b4b4} Te6edf3returns Te6edf3MutableStateFlowTb4b4b4(Tff7b72nullTb4b4b4)
Te6edf3every Tb4b4b4{ Te6edf3nodeRequestActionsTb4b4b4.Te6edf3lastRequestNeighborTimes Tb4b4b4} Te6edf3returns Te6edf3MutableStateFlowTb4b4b4(Te6edf3emptyMapTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3every Tb4b4b4{ Te6edf3nodeRepositoryTb4b4b4.Te6edf3nodeDBbyNum Tb4b4b4} Te6edf3returns Te6edf3MutableStateFlowTb4b4b4(Te6edf3emptyMapTb4b4b4(Tb4b4b4)Tb4b4b4)

T8b949e// Mock the case where we get node details
Te6edf3every Tb4b4b4{ Te6edf3getNodeDetailsUseCaseTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4} Te6edf3returns Te6edf3flowOfTb4b4b4(Te6edf3NodeDetailUiStateTb4b4b4(Tb4b4b4)Tb4b4b4)

Te6edf3viewModel Tff7b72= Te6edf3createViewModelTb4b4b4(Tb4b4b4)
Tb4b4b4}

Tff7b72private Tff7b72fun Td2a8ffcreateViewModelTb4b4b4(Te6edf3destNumTb4b4b4: Tffa657Int Tff7b72= T79c0ff1T79c0ff2T79c0ff3T79c0ff4Tb4b4b4) Tff7b72= Te6edf3MetricsViewModelTb4b4b4(
Te6edf3destNum Tff7b72= Te6edf3destNumTb4b4b4,
Te6edf3dispatchers Tff7b72= Te6edf3dispatchersTb4b4b4,
Te6edf3meshLogRepository Tff7b72= Te6edf3meshLogRepositoryTb4b4b4,
Te6edf3serviceRepository Tff7b72= Te6edf3serviceRepositoryTb4b4b4,
Te6edf3nodeRepository Tff7b72= Te6edf3nodeRepositoryTb4b4b4,
Te6edf3tracerouteSnapshotRepository Tff7b72= Te6edf3tracerouteSnapshotRepositoryTb4b4b4,
Te6edf3nodeRequestActions Tff7b72= Te6edf3nodeRequestActionsTb4b4b4,
Te6edf3alertManager Tff7b72= Te6edf3alertManagerTb4b4b4,
Te6edf3getNodeDetailsUseCase Tff7b72= Te6edf3getNodeDetailsUseCaseTb4b4b4,
Te6edf3fileService Tff7b72= Te6edf3fileServiceTb4b4b4,
Tb4b4b4)

Tf0883e@AfterTest
Tff7b72fun Td2a8fftearDownTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3DispatchersTb4b4b4.Te6edf3resetMainTb4b4b4(Tb4b4b4)
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8fftestInitializationTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3assertNotNullTb4b4b4(Te6edf3viewModelTb4b4b4)
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`state reflects updates from getNodeDetailsUseCase`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTestTb4b4b4(Te6edf3testDispatcherTb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3nodeDetailFlow Tff7b72= Te6edf3MutableStateFlowTb4b4b4(Te6edf3NodeDetailUiStateTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3every Tb4b4b4{ Te6edf3getNodeDetailsUseCaseTb4b4b4(T79c0ff1T79c0ff2T79c0ff3T79c0ff4Tb4b4b4) Tb4b4b4} Te6edf3returns Te6edf3nodeDetailFlowTb4b4b4.Te6edf3asStateFlowTb4b4b4(Tb4b4b4)

Tff7b72val Te6edf3vm Tff7b72= Te6edf3createViewModelTb4b4b4(Tb4b4b4)
Te6edf3vmTb4b4b4.Te6edf3stateTb4b4b4.Te6edf3test Tb4b4b4{
Te6edf3assertEqualsTb4b4b4(Te6edf3MetricsStateTb4b4b4.Te6edf3EmptyTb4b4b4, Te6edf3awaitItemTb4b4b4(Tb4b4b4)Tb4b4b4)

Tff7b72val Te6edf3newState Tff7b72= Te6edf3MetricsStateTb4b4b4(Te6edf3isFahrenheit Tff7b72= Tff7b72trueTb4b4b4)
Te6edf3nodeDetailFlowTb4b4b4.Te6edf3value Tff7b72= Te6edf3NodeDetailUiStateTb4b4b4(Te6edf3metricsState Tff7b72= Te6edf3newStateTb4b4b4)

Te6edf3assertEqualsTb4b4b4(Te6edf3newStateTb4b4b4, Te6edf3awaitItemTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3cancelAndIgnoreRemainingEventsTb4b4b4(Tb4b4b4)
Tb4b4b4}
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`availableTimeFrames filters based on oldest data`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTestTb4b4b4(Te6edf3testDispatcherTb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3now Tff7b72= Te6edf3orgTb4b4b4.Te6edf3meshtasticTb4b4b4.Te6edf3coreTb4b4b4.Te6edf3commonTb4b4b4.Te6edf3utilTb4b4b4.Te6edf3nowSeconds

Tff7b72val Te6edf3nodeDetailFlow Tff7b72= Te6edf3MutableStateFlowTb4b4b4(Te6edf3NodeDetailUiStateTb4b4b4(Tb4b4b4)Tb4b4b4)
Te6edf3every Tb4b4b4{ Te6edf3getNodeDetailsUseCaseTb4b4b4(T79c0ff1T79c0ff2T79c0ff3T79c0ff4Tb4b4b4) Tb4b4b4} Te6edf3returns Te6edf3nodeDetailFlowTb4b4b4.Te6edf3asStateFlowTb4b4b4(Tb4b4b4)

Tff7b72val Te6edf3vm Tff7b72= Te6edf3createViewModelTb4b4b4(Tb4b4b4)
Te6edf3vmTb4b4b4.Te6edf3availableTimeFramesTb4b4b4.Te6edf3test Tb4b4b4{
T8b949e// Skip initial values
Tff7b72var Te6edf3current Tff7b72= Te6edf3awaitItemTb4b4b4(Tb4b4b4)

T8b949e// Provide data from 2 hours ago (7200 seconds)
T8b949e// This should make ONE_HOUR available, but not TWENTY_FOUR_HOURS
Tff7b72val Te6edf3twoHoursAgo Tff7b72= Te6edf3now Tff7b72- T79c0ff7T79c0ff2T79c0ff0T79c0ff0
Te6edf3nodeDetailFlowTb4b4b4.Te6edf3value Tff7b72=
Te6edf3NodeDetailUiStateTb4b4b4(
Te6edf3node Tff7b72=
Te6edf3orgTb4b4b4.Te6edf3meshtasticTb4b4b4.Te6edf3coreTb4b4b4.Te6edf3modelTb4b4b4.Te6edf3NodeTb4b4b4(Te6edf3num Tff7b72= T79c0ff1T79c0ff2T79c0ff3T79c0ff4Tb4b4b4, Te6edf3user Tff7b72= Te6edf3orgTb4b4b4.Te6edf3meshtasticTb4b4b4.Te6edf3protoTb4b4b4.Te6edf3UserTb4b4b4(Te6edf3id Tff7b72= Ta5d6ff"Ta5d6ff!1234Ta5d6ff"Tb4b4b4)Tb4b4b4)Tb4b4b4,
Te6edf3environmentState Tff7b72=
Te6edf3EnvironmentMetricsStateTb4b4b4(Te6edf3environmentMetrics Tff7b72= Te6edf3listOfTb4b4b4(Te6edf3TelemetryTb4b4b4(Te6edf3time Tff7b72= Te6edf3twoHoursAgoTb4b4b4.Te6edf3toIntTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4,
Tb4b4b4)

T8b949e// We might get multiple emissions as flows propagate
Te6edf3current Tff7b72= Te6edf3awaitItemTb4b4b4(Tb4b4b4)
Tff7b72while Tb4b4b4(Te6edf3currentTb4b4b4.Te6edf3size Tff7b72=Tff7b72= Te6edf3TimeFrameTb4b4b4.Te6edf3entriesTb4b4b4.Te6edf3sizeTb4b4b4) Tb4b4b4{ T8b949e// Skip the initial "all" if it's still there
Te6edf3current Tff7b72= Te6edf3awaitItemTb4b4b4(Tb4b4b4)
Tb4b4b4}

Te6edf3assertTrueTb4b4b4(Te6edf3currentTb4b4b4.Te6edf3containsTb4b4b4(Te6edf3TimeFrameTb4b4b4.Te6edf3ONE_HOURTb4b4b4)Tb4b4b4)
Te6edf3assertTrueTb4b4b4(Tff7b72!Te6edf3currentTb4b4b4.Te6edf3containsTb4b4b4(Te6edf3TimeFrameTb4b4b4.Te6edf3TWENTY_FOUR_HOURSTb4b4b4)Tb4b4b4, Ta5d6ff"Ta5d6ffShould not contain 24h for 2h old dataTa5d6ff"Tb4b4b4)

T8b949e// Provide data from 8 days ago
Tff7b72val Te6edf3eightDaysAgo Tff7b72= Te6edf3now Tff7b72- Tb4b4b4(T79c0ff8 Tff7b72* T79c0ff2T79c0ff4 Tff7b72* T79c0ff3T79c0ff6T79c0ff0T79c0ff0Tb4b4b4)
Te6edf3nodeDetailFlowTb4b4b4.Te6edf3value Tff7b72=
Te6edf3NodeDetailUiStateTb4b4b4(
Te6edf3node Tff7b72=
Te6edf3orgTb4b4b4.Te6edf3meshtasticTb4b4b4.Te6edf3coreTb4b4b4.Te6edf3modelTb4b4b4.Te6edf3NodeTb4b4b4(Te6edf3num Tff7b72= T79c0ff1T79c0ff2T79c0ff3T79c0ff4Tb4b4b4, Te6edf3user Tff7b72= Te6edf3orgTb4b4b4.Te6edf3meshtasticTb4b4b4.Te6edf3protoTb4b4b4.Te6edf3UserTb4b4b4(Te6edf3id Tff7b72= Ta5d6ff"Ta5d6ff!1234Ta5d6ff"Tb4b4b4)Tb4b4b4)Tb4b4b4,
Te6edf3environmentState Tff7b72=
Te6edf3EnvironmentMetricsStateTb4b4b4(
Te6edf3environmentMetrics Tff7b72= Te6edf3listOfTb4b4b4(Te6edf3TelemetryTb4b4b4(Te6edf3time Tff7b72= Te6edf3eightDaysAgoTb4b4b4.Te6edf3toIntTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4,
Tb4b4b4)Tb4b4b4,
Tb4b4b4)

Te6edf3current Tff7b72= Te6edf3awaitItemTb4b4b4(Tb4b4b4)
Te6edf3assertTrueTb4b4b4(Te6edf3currentTb4b4b4.Te6edf3containsTb4b4b4(Te6edf3TimeFrameTb4b4b4.Te6edf3SEVEN_DAYSTb4b4b4)Tb4b4b4)

Te6edf3cancelAndIgnoreRemainingEventsTb4b4b4(Tb4b4b4)
Tb4b4b4}
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`savePositionCSV writes correct data`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTestTb4b4b4(Te6edf3testDispatcherTb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3testPosition Tff7b72=
Te6edf3PositionTb4b4b4(
Te6edf3latitude_i Tff7b72= T79c0ff1T79c0ff2T79c0ff3T79c0ff4T79c0ff5T79c0ff6T79c0ff7T79c0ff8T79c0ff9Tb4b4b4,
Te6edf3longitude_i Tff7b72= Tff7b72-T79c0ff9T79c0ff8T79c0ff7T79c0ff6T79c0ff5T79c0ff4T79c0ff3T79c0ff2T79c0ff1Tb4b4b4,
Te6edf3altitude Tff7b72= T79c0ff1T79c0ff0T79c0ff0Tb4b4b4,
Te6edf3sats_in_view Tff7b72= T79c0ff5Tb4b4b4,
Te6edf3ground_speed Tff7b72= T79c0ff1T79c0ff0Tb4b4b4,
Te6edf3ground_track Tff7b72= T79c0ff1T79c0ff2T79c0ff3T79c0ff4T79c0ff5T79c0ff6Tb4b4b4,
Te6edf3time Tff7b72= T79c0ff1T79c0ff7T79c0ff0T79c0ff0T79c0ff0T79c0ff0T79c0ff0T79c0ff0T79c0ff0T79c0ff0Tb4b4b4,
Tb4b4b4)

Tff7b72val Te6edf3nodeDetailFlow Tff7b72=
Te6edf3MutableStateFlowTb4b4b4(Te6edf3NodeDetailUiStateTb4b4b4(Te6edf3metricsState Tff7b72= Te6edf3MetricsStateTb4b4b4(Te6edf3positionLogs Tff7b72= Te6edf3listOfTb4b4b4(Te6edf3testPositionTb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4)
Te6edf3every Tb4b4b4{ Te6edf3getNodeDetailsUseCaseTb4b4b4(T79c0ff1T79c0ff2T79c0ff3T79c0ff4Tb4b4b4) Tb4b4b4} Te6edf3returns Te6edf3nodeDetailFlowTb4b4b4.Te6edf3asStateFlowTb4b4b4(Tb4b4b4)

Tff7b72val Te6edf3buffer Tff7b72= Te6edf3BufferTb4b4b4(Tb4b4b4)
Te6edf3everySuspend Tb4b4b4{ Te6edf3fileServiceTb4b4b4.Te6edf3writeTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4} Te6edf3calls
Tb4b4b4{ Te6edf3args Tff7b72-Tff7b72>
Tff7b72val Te6edf3block Tff7b72= Te6edf3argsTb4b4b4.Te6edf3argTff7b72<Te6edf3suspend Tb4b4b4(Te6edf3BufferedSinkTb4b4b4) Tff7b72-Tff7b72> Tffa657UnitTff7b72>Tb4b4b4(T79c0ff1Tb4b4b4)
Te6edf3blockTb4b4b4(Te6edf3bufferTb4b4b4)
Tff7b72true
Tb4b4b4}

Tff7b72val Te6edf3vm Tff7b72= Te6edf3createViewModelTb4b4b4(Tb4b4b4)
T8b949e// Wait for state to be collected so it's not Empty when savePositionCSV is called
Te6edf3vmTb4b4b4.Te6edf3stateTb4b4b4.Te6edf3test Tb4b4b4{
Te6edf3awaitItemTb4b4b4(Tb4b4b4) T8b949e// Empty
Te6edf3awaitItemTb4b4b4(Tb4b4b4) T8b949e// with position

Tff7b72val Te6edf3uri Tff7b72= Te6edf3CommonUriTb4b4b4.Te6edf3parseTb4b4b4(Ta5d6ff"Ta5d6ffcontent://testTa5d6ff"Tb4b4b4)
Te6edf3vmTb4b4b4.Te6edf3savePositionCSVTb4b4b4(Te6edf3uriTb4b4b4, Te6edf3listOfTb4b4b4(Te6edf3testPositionTb4b4b4)Tb4b4b4)
Te6edf3runCurrentTb4b4b4(Tb4b4b4)

Te6edf3verifySuspend Tb4b4b4{ Te6edf3fileServiceTb4b4b4.Te6edf3writeTb4b4b4(Te6edf3uriTb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4}

Tff7b72val Te6edf3csvOutput Tff7b72= Te6edf3bufferTb4b4b4.Te6edf3readUtf8Tb4b4b4(Tb4b4b4)
Te6edf3assertTrueTb4b4b4(Te6edf3csvOutputTb4b4b4.Te6edf3startsWithTb4b4b4(Ta5d6ff"Ta5d6ff\"Ta5d6ffdateTa5d6ff\"Ta5d6ff,Ta5d6ff\"Ta5d6fftimeTa5d6ff\"Ta5d6ff,Ta5d6ff\"Ta5d6fflatitudeTa5d6ff\"Ta5d6ff,Ta5d6ff\"Ta5d6fflongitudeTa5d6ff\"Ta5d6ff"Tb4b4b4)Tb4b4b4)
Te6edf3assertTrueTb4b4b4(Te6edf3csvOutputTb4b4b4.Te6edf3containsTb4b4b4(Ta5d6ff"Ta5d6ff12.3456789Ta5d6ff"Tb4b4b4)Tb4b4b4)
Te6edf3assertTrueTb4b4b4(Te6edf3csvOutputTb4b4b4.Te6edf3containsTb4b4b4(Ta5d6ff"Ta5d6ff-98.7654321Ta5d6ff"Tb4b4b4)Tb4b4b4)
Te6edf3assertTrueTb4b4b4(Te6edf3csvOutputTb4b4b4.Te6edf3containsTb4b4b4(Ta5d6ff"Ta5d6ff\"Ta5d6ff100Ta5d6ff\"Ta5d6ff,Ta5d6ff\"Ta5d6ff5Ta5d6ff\"Ta5d6ff,Ta5d6ff\"Ta5d6ff10Ta5d6ff\"Ta5d6ff,Ta5d6ff\"Ta5d6ff1.23Ta5d6ff\"Ta5d6ff"Tb4b4b4)Tb4b4b4)

Te6edf3cancelAndIgnoreRemainingEventsTb4b4b4(Tb4b4b4)
Tb4b4b4}
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`saveDeviceMetricsCSV writes correct data`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTestTb4b4b4(Te6edf3testDispatcherTb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3testTelemetry Tff7b72=
Te6edf3TelemetryTb4b4b4(
Te6edf3time Tff7b72= T79c0ff1T79c0ff7T79c0ff0T79c0ff0T79c0ff0T79c0ff0T79c0ff0T79c0ff0T79c0ff0T79c0ff0Tb4b4b4,
Te6edf3device_metrics Tff7b72=
Te6edf3DeviceMetricsTb4b4b4(
Te6edf3battery_level Tff7b72= T79c0ff8T79c0ff0Tb4b4b4,
Te6edf3voltage Tff7b72= T79c0ff4.1fTb4b4b4,
Te6edf3channel_utilization Tff7b72= T79c0ff1T79c0ff2.5fTb4b4b4,
Te6edf3air_util_tx Tff7b72= T79c0ff3.25fTb4b4b4,
Te6edf3uptime_seconds Tff7b72= T79c0ff3T79c0ff6T79c0ff0T79c0ff0Tb4b4b4,
Tb4b4b4)Tb4b4b4,
Tb4b4b4)

Tff7b72val Te6edf3nodeDetailFlow Tff7b72=
Te6edf3MutableStateFlowTb4b4b4(Te6edf3NodeDetailUiStateTb4b4b4(Te6edf3metricsState Tff7b72= Te6edf3MetricsStateTb4b4b4(Te6edf3deviceMetrics Tff7b72= Te6edf3listOfTb4b4b4(Te6edf3testTelemetryTb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4)
Te6edf3every Tb4b4b4{ Te6edf3getNodeDetailsUseCaseTb4b4b4(T79c0ff1T79c0ff2T79c0ff3T79c0ff4Tb4b4b4) Tb4b4b4} Te6edf3returns Te6edf3nodeDetailFlowTb4b4b4.Te6edf3asStateFlowTb4b4b4(Tb4b4b4)

Tff7b72val Te6edf3buffer Tff7b72= Te6edf3BufferTb4b4b4(Tb4b4b4)
Te6edf3everySuspend Tb4b4b4{ Te6edf3fileServiceTb4b4b4.Te6edf3writeTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4} Te6edf3calls
Tb4b4b4{ Te6edf3args Tff7b72-Tff7b72>
Tff7b72val Te6edf3block Tff7b72= Te6edf3argsTb4b4b4.Te6edf3argTff7b72<Te6edf3suspend Tb4b4b4(Te6edf3BufferedSinkTb4b4b4) Tff7b72-Tff7b72> Tffa657UnitTff7b72>Tb4b4b4(T79c0ff1Tb4b4b4)
Te6edf3blockTb4b4b4(Te6edf3bufferTb4b4b4)
Tff7b72true
Tb4b4b4}

Tff7b72val Te6edf3vm Tff7b72= Te6edf3createViewModelTb4b4b4(Tb4b4b4)
Te6edf3vmTb4b4b4.Te6edf3stateTb4b4b4.Te6edf3test Tb4b4b4{
Te6edf3awaitItemTb4b4b4(Tb4b4b4)
Te6edf3awaitItemTb4b4b4(Tb4b4b4)

Tff7b72val Te6edf3uri Tff7b72= Te6edf3CommonUriTb4b4b4.Te6edf3parseTb4b4b4(Ta5d6ff"Ta5d6ffcontent://testTa5d6ff"Tb4b4b4)
Te6edf3vmTb4b4b4.Te6edf3saveDeviceMetricsCSVTb4b4b4(Te6edf3uriTb4b4b4, Te6edf3listOfTb4b4b4(Te6edf3testTelemetryTb4b4b4)Tb4b4b4)
Te6edf3runCurrentTb4b4b4(Tb4b4b4)

Te6edf3verifySuspend Tb4b4b4{ Te6edf3fileServiceTb4b4b4.Te6edf3writeTb4b4b4(Te6edf3uriTb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4}

Tff7b72val Te6edf3csvOutput Tff7b72= Te6edf3bufferTb4b4b4.Te6edf3readUtf8Tb4b4b4(Tb4b4b4)
Te6edf3assertTrueTb4b4b4(
Te6edf3csvOutputTb4b4b4.Te6edf3startsWithTb4b4b4(
Ta5d6ff"Ta5d6ff\"Ta5d6ffdateTa5d6ff\"Ta5d6ff,Ta5d6ff\"Ta5d6fftimeTa5d6ff\"Ta5d6ff,Ta5d6ff\"Ta5d6ffbatteryLevelTa5d6ff\"Ta5d6ff,Ta5d6ff\"Ta5d6ffvoltageTa5d6ff\"Ta5d6ff,Ta5d6ff\"Ta5d6ffchannelUtilizationTa5d6ff\"Ta5d6ff,Ta5d6ff\"Ta5d6ffairUtilTxTa5d6ff\"Ta5d6ff,Ta5d6ff\"Ta5d6ffuptimeSecondsTa5d6ff\"Ta5d6ff"Tb4b4b4,
Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Te6edf3assertTrueTb4b4b4(Te6edf3csvOutputTb4b4b4.Te6edf3containsTb4b4b4(Ta5d6ff"Ta5d6ff\"Ta5d6ff80Ta5d6ff\"Ta5d6ff,Ta5d6ff\"Ta5d6ff4.1Ta5d6ff\"Ta5d6ff,Ta5d6ff\"Ta5d6ff12.5Ta5d6ff\"Ta5d6ff,Ta5d6ff\"Ta5d6ff3.25Ta5d6ff\"Ta5d6ff,Ta5d6ff\"Ta5d6ff3600Ta5d6ff\"Ta5d6ff"Tb4b4b4)Tb4b4b4)

Te6edf3cancelAndIgnoreRemainingEventsTb4b4b4(Tb4b4b4)
Tb4b4b4}
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`saveEnvironmentMetricsCSV writes correct data`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTestTb4b4b4(Te6edf3testDispatcherTb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3testTelemetry Tff7b72=
Te6edf3TelemetryTb4b4b4(
Te6edf3time Tff7b72= T79c0ff1T79c0ff7T79c0ff0T79c0ff0T79c0ff0T79c0ff0T79c0ff0T79c0ff0T79c0ff0T79c0ff0Tb4b4b4,
Te6edf3environment_metrics Tff7b72=
Te6edf3EnvironmentMetricsTb4b4b4(
Te6edf3temperature Tff7b72= T79c0ff2T79c0ff1.5fTb4b4b4,
Te6edf3relative_humidity Tff7b72= T79c0ff5T79c0ff5.5fTb4b4b4,
Te6edf3barometric_pressure Tff7b72= T79c0ff1T79c0ff0T79c0ff1T79c0ff3.25fTb4b4b4,
Te6edf3gas_resistance Tff7b72= T79c0ff1T79c0ff2.3fTb4b4b4,
Te6edf3iaq Tff7b72= T79c0ff4T79c0ff2Tb4b4b4,
Te6edf3wind_speed Tff7b72= T79c0ff5.5fTb4b4b4,
Te6edf3wind_direction Tff7b72= T79c0ff1T79c0ff8T79c0ff0Tb4b4b4,
Te6edf3soil_temperature Tff7b72= T79c0ff1T79c0ff8.75fTb4b4b4,
Te6edf3soil_moisture Tff7b72= T79c0ff6T79c0ff5Tb4b4b4,
Te6edf3one_wire_temperature Tff7b72= Te6edf3listOfTb4b4b4(T79c0ff1fTb4b4b4, T79c0ff2fTb4b4b4, T79c0ff3fTb4b4b4)Tb4b4b4,
Tb4b4b4)Tb4b4b4,
Tb4b4b4)

Tff7b72val Te6edf3nodeDetailFlow Tff7b72=
Te6edf3MutableStateFlowTb4b4b4(
Te6edf3NodeDetailUiStateTb4b4b4(
Te6edf3metricsState Tff7b72= Te6edf3MetricsStateTb4b4b4(Te6edf3deviceMetrics Tff7b72= Te6edf3emptyListTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4,
Te6edf3environmentState Tff7b72= Te6edf3EnvironmentMetricsStateTb4b4b4(Te6edf3environmentMetrics Tff7b72= Te6edf3listOfTb4b4b4(Te6edf3testTelemetryTb4b4b4)Tb4b4b4)Tb4b4b4,
Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Te6edf3every Tb4b4b4{ Te6edf3getNodeDetailsUseCaseTb4b4b4(T79c0ff1T79c0ff2T79c0ff3T79c0ff4Tb4b4b4) Tb4b4b4} Te6edf3returns Te6edf3nodeDetailFlowTb4b4b4.Te6edf3asStateFlowTb4b4b4(Tb4b4b4)

Tff7b72val Te6edf3buffer Tff7b72= Te6edf3BufferTb4b4b4(Tb4b4b4)
Te6edf3everySuspend Tb4b4b4{ Te6edf3fileServiceTb4b4b4.Te6edf3writeTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4} Te6edf3calls
Tb4b4b4{ Te6edf3args Tff7b72-Tff7b72>
Tff7b72val Te6edf3block Tff7b72= Te6edf3argsTb4b4b4.Te6edf3argTff7b72<Te6edf3suspend Tb4b4b4(Te6edf3BufferedSinkTb4b4b4) Tff7b72-Tff7b72> Tffa657UnitTff7b72>Tb4b4b4(T79c0ff1Tb4b4b4)
Te6edf3blockTb4b4b4(Te6edf3bufferTb4b4b4)
Tff7b72true
Tb4b4b4}

Tff7b72val Te6edf3vm Tff7b72= Te6edf3createViewModelTb4b4b4(Tb4b4b4)
Te6edf3vmTb4b4b4.Te6edf3stateTb4b4b4.Te6edf3test Tb4b4b4{
Te6edf3awaitItemTb4b4b4(Tb4b4b4)

Tff7b72val Te6edf3uri Tff7b72= Te6edf3CommonUriTb4b4b4.Te6edf3parseTb4b4b4(Ta5d6ff"Ta5d6ffcontent://testTa5d6ff"Tb4b4b4)
Te6edf3vmTb4b4b4.Te6edf3saveEnvironmentMetricsCSVTb4b4b4(Te6edf3uriTb4b4b4, Te6edf3listOfTb4b4b4(Te6edf3testTelemetryTb4b4b4)Tb4b4b4)
Te6edf3runCurrentTb4b4b4(Tb4b4b4)

Te6edf3verifySuspend Tb4b4b4{ Te6edf3fileServiceTb4b4b4.Te6edf3writeTb4b4b4(Te6edf3uriTb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4}

Tff7b72val Te6edf3csvOutput Tff7b72= Te6edf3bufferTb4b4b4.Te6edf3readUtf8Tb4b4b4(Tb4b4b4)
Te6edf3assertTrueTb4b4b4(
Te6edf3csvOutputTb4b4b4.Te6edf3startsWithTb4b4b4(
Ta5d6ff"Ta5d6ff\"Ta5d6ffdateTa5d6ff\"Ta5d6ff,Ta5d6ff\"Ta5d6fftimeTa5d6ff\"Ta5d6ff,Ta5d6ff\"Ta5d6fftemperatureTa5d6ff\"Ta5d6ff,Ta5d6ff\"Ta5d6ffrelativeHumidityTa5d6ff\"Ta5d6ff,Ta5d6ff\"Ta5d6ffbarometricPressureTa5d6ff\"Ta5d6ff,Ta5d6ff\"Ta5d6ffgasResistanceTa5d6ff\"Ta5d6ff,Ta5d6ff\"Ta5d6ffiaqTa5d6ff\"Ta5d6ff,Ta5d6ff\"Ta5d6ffwindSpeedTa5d6ff\"Ta5d6ff,Ta5d6ff\"Ta5d6ffwindDirectionTa5d6ff\"Ta5d6ff,Ta5d6ff\"Ta5d6ffsoilTemperatureTa5d6ff\"Ta5d6ff,Ta5d6ff\"Ta5d6ffsoilMoistureTa5d6ff\"Ta5d6ff,Ta5d6ff\"Ta5d6ffoneWireTemp1Ta5d6ff\"Ta5d6ff,Ta5d6ff\"Ta5d6ffoneWireTemp2Ta5d6ff\"Ta5d6ff,Ta5d6ff\"Ta5d6ffoneWireTemp3Ta5d6ff\"Ta5d6ff,Ta5d6ff\"Ta5d6ffoneWireTemp4Ta5d6ff\"Ta5d6ff,Ta5d6ff\"Ta5d6ffoneWireTemp5Ta5d6ff\"Ta5d6ff,Ta5d6ff\"Ta5d6ffoneWireTemp6Ta5d6ff\"Ta5d6ff,Ta5d6ff\"Ta5d6ffoneWireTemp7Ta5d6ff\"Ta5d6ff,Ta5d6ff\"Ta5d6ffoneWireTemp8Ta5d6ff\"Ta5d6ff"Tb4b4b4,
Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Te6edf3assertTrueTb4b4b4(
Te6edf3csvOutputTb4b4b4.Te6edf3containsTb4b4b4(
Ta5d6ff"Ta5d6ff\"Ta5d6ff21.5Ta5d6ff\"Ta5d6ff,Ta5d6ff\"Ta5d6ff55.5Ta5d6ff\"Ta5d6ff,Ta5d6ff\"Ta5d6ff1013.25Ta5d6ff\"Ta5d6ff,Ta5d6ff\"Ta5d6ff12.3Ta5d6ff\"Ta5d6ff,Ta5d6ff\"Ta5d6ff42Ta5d6ff\"Ta5d6ff,Ta5d6ff\"Ta5d6ff5.5Ta5d6ff\"Ta5d6ff,Ta5d6ff\"Ta5d6ff180Ta5d6ff\"Ta5d6ff,Ta5d6ff\"Ta5d6ff18.75Ta5d6ff\"Ta5d6ff,Ta5d6ff\"Ta5d6ff65Ta5d6ff\"Ta5d6ff,Ta5d6ff\"Ta5d6ff1.0Ta5d6ff\"Ta5d6ff,Ta5d6ff\"Ta5d6ff2.0Ta5d6ff\"Ta5d6ff,Ta5d6ff\"Ta5d6ff3.0Ta5d6ff\"Ta5d6ff,Ta5d6ff\"Ta5d6ff\"Ta5d6ff,Ta5d6ff\"Ta5d6ff\"Ta5d6ff,Ta5d6ff\"Ta5d6ff\"Ta5d6ff,Ta5d6ff\"Ta5d6ff\"Ta5d6ff,Ta5d6ff\"Ta5d6ff\"Ta5d6ff"Tb4b4b4,
Tb4b4b4)Tb4b4b4,
Tb4b4b4)

Te6edf3cancelAndIgnoreRemainingEventsTb4b4b4(Tb4b4b4)
Tb4b4b4}
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`saveSignalMetricsCSV writes correct data`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTestTb4b4b4(Te6edf3testDispatcherTb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3testPacket Tff7b72= Te6edf3MeshPacketTb4b4b4(Te6edf3rx_time Tff7b72= T79c0ff1T79c0ff7T79c0ff0T79c0ff0T79c0ff0T79c0ff0T79c0ff0T79c0ff0T79c0ff0T79c0ff0Tb4b4b4, Te6edf3rx_rssi Tff7b72= Tff7b72-T79c0ff1T79c0ff0T79c0ff5Tb4b4b4, Te6edf3rx_snr Tff7b72= T79c0ff7.5fTb4b4b4)

Tff7b72val Te6edf3nodeDetailFlow Tff7b72=
Te6edf3MutableStateFlowTb4b4b4(Te6edf3NodeDetailUiStateTb4b4b4(Te6edf3metricsState Tff7b72= Te6edf3MetricsStateTb4b4b4(Te6edf3signalMetrics Tff7b72= Te6edf3listOfTb4b4b4(Te6edf3testPacketTb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4)
Te6edf3every Tb4b4b4{ Te6edf3getNodeDetailsUseCaseTb4b4b4(T79c0ff1T79c0ff2T79c0ff3T79c0ff4Tb4b4b4) Tb4b4b4} Te6edf3returns Te6edf3nodeDetailFlowTb4b4b4.Te6edf3asStateFlowTb4b4b4(Tb4b4b4)

Tff7b72val Te6edf3buffer Tff7b72= Te6edf3BufferTb4b4b4(Tb4b4b4)
Te6edf3everySuspend Tb4b4b4{ Te6edf3fileServiceTb4b4b4.Te6edf3writeTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4} Te6edf3calls
Tb4b4b4{ Te6edf3args Tff7b72-Tff7b72>
Tff7b72val Te6edf3block Tff7b72= Te6edf3argsTb4b4b4.Te6edf3argTff7b72<Te6edf3suspend Tb4b4b4(Te6edf3BufferedSinkTb4b4b4) Tff7b72-Tff7b72> Tffa657UnitTff7b72>Tb4b4b4(T79c0ff1Tb4b4b4)
Te6edf3blockTb4b4b4(Te6edf3bufferTb4b4b4)
Tff7b72true
Tb4b4b4}

Tff7b72val Te6edf3vm Tff7b72= Te6edf3createViewModelTb4b4b4(Tb4b4b4)
Te6edf3vmTb4b4b4.Te6edf3stateTb4b4b4.Te6edf3test Tb4b4b4{
Te6edf3awaitItemTb4b4b4(Tb4b4b4)
Te6edf3awaitItemTb4b4b4(Tb4b4b4)

Tff7b72val Te6edf3uri Tff7b72= Te6edf3CommonUriTb4b4b4.Te6edf3parseTb4b4b4(Ta5d6ff"Ta5d6ffcontent://testTa5d6ff"Tb4b4b4)
Te6edf3vmTb4b4b4.Te6edf3saveSignalMetricsCSVTb4b4b4(Te6edf3uriTb4b4b4, Te6edf3listOfTb4b4b4(Te6edf3testPacketTb4b4b4)Tb4b4b4)
Te6edf3runCurrentTb4b4b4(Tb4b4b4)

Te6edf3verifySuspend Tb4b4b4{ Te6edf3fileServiceTb4b4b4.Te6edf3writeTb4b4b4(Te6edf3uriTb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4}

Tff7b72val Te6edf3csvOutput Tff7b72= Te6edf3bufferTb4b4b4.Te6edf3readUtf8Tb4b4b4(Tb4b4b4)
Te6edf3assertTrueTb4b4b4(Te6edf3csvOutputTb4b4b4.Te6edf3startsWithTb4b4b4(Ta5d6ff"Ta5d6ff\"Ta5d6ffdateTa5d6ff\"Ta5d6ff,Ta5d6ff\"Ta5d6fftimeTa5d6ff\"Ta5d6ff,Ta5d6ff\"Ta5d6ffrssiTa5d6ff\"Ta5d6ff,Ta5d6ff\"Ta5d6ffsnrTa5d6ff\"Ta5d6ff"Tb4b4b4)Tb4b4b4)
Te6edf3assertTrueTb4b4b4(Te6edf3csvOutputTb4b4b4.Te6edf3containsTb4b4b4(Ta5d6ff"Ta5d6ff\"Ta5d6ff-105Ta5d6ff\"Ta5d6ff,Ta5d6ff\"Ta5d6ff7.5Ta5d6ff\"Ta5d6ff"Tb4b4b4)Tb4b4b4)

Te6edf3cancelAndIgnoreRemainingEventsTb4b4b4(Tb4b4b4)
Tb4b4b4}
Tb4b4b4}

Tf0883e@Test
Tff7b72fun Td2a8ff`savePowerMetricsCSV writes correct data`Tb4b4b4(Tb4b4b4) Tff7b72= Te6edf3runTestTb4b4b4(Te6edf3testDispatcherTb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3testTelemetry Tff7b72=
Te6edf3TelemetryTb4b4b4(
Te6edf3time Tff7b72= T79c0ff1T79c0ff7T79c0ff0T79c0ff0T79c0ff0T79c0ff0T79c0ff0T79c0ff0T79c0ff0T79c0ff0Tb4b4b4,
Te6edf3power_metrics Tff7b72=
Te6edf3PowerMetricsTb4b4b4(
Te6edf3ch1_voltage Tff7b72= T79c0ff3.3fTb4b4b4,
Te6edf3ch1_current Tff7b72= T79c0ff0.1fTb4b4b4,
Te6edf3ch2_voltage Tff7b72= T79c0ff5.0fTb4b4b4,
Te6edf3ch2_current Tff7b72= T79c0ff0.2fTb4b4b4,
Te6edf3ch3_voltage Tff7b72= T79c0ff1T79c0ff2.0fTb4b4b4,
Te6edf3ch3_current Tff7b72= T79c0ff0.3fTb4b4b4,
Tb4b4b4)Tb4b4b4,
Tb4b4b4)

Tff7b72val Te6edf3nodeDetailFlow Tff7b72=
Te6edf3MutableStateFlowTb4b4b4(Te6edf3NodeDetailUiStateTb4b4b4(Te6edf3metricsState Tff7b72= Te6edf3MetricsStateTb4b4b4(Te6edf3powerMetrics Tff7b72= Te6edf3listOfTb4b4b4(Te6edf3testTelemetryTb4b4b4)Tb4b4b4)Tb4b4b4)Tb4b4b4)
Te6edf3every Tb4b4b4{ Te6edf3getNodeDetailsUseCaseTb4b4b4(T79c0ff1T79c0ff2T79c0ff3T79c0ff4Tb4b4b4) Tb4b4b4} Te6edf3returns Te6edf3nodeDetailFlowTb4b4b4.Te6edf3asStateFlowTb4b4b4(Tb4b4b4)

Tff7b72val Te6edf3buffer Tff7b72= Te6edf3BufferTb4b4b4(Tb4b4b4)
Te6edf3everySuspend Tb4b4b4{ Te6edf3fileServiceTb4b4b4.Te6edf3writeTb4b4b4(Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4} Te6edf3calls
Tb4b4b4{ Te6edf3args Tff7b72-Tff7b72>
Tff7b72val Te6edf3block Tff7b72= Te6edf3argsTb4b4b4.Te6edf3argTff7b72<Te6edf3suspend Tb4b4b4(Te6edf3BufferedSinkTb4b4b4) Tff7b72-Tff7b72> Tffa657UnitTff7b72>Tb4b4b4(T79c0ff1Tb4b4b4)
Te6edf3blockTb4b4b4(Te6edf3bufferTb4b4b4)
Tff7b72true
Tb4b4b4}

Tff7b72val Te6edf3vm Tff7b72= Te6edf3createViewModelTb4b4b4(Tb4b4b4)
Te6edf3vmTb4b4b4.Te6edf3stateTb4b4b4.Te6edf3test Tb4b4b4{
Te6edf3awaitItemTb4b4b4(Tb4b4b4)
Te6edf3awaitItemTb4b4b4(Tb4b4b4)

Tff7b72val Te6edf3uri Tff7b72= Te6edf3CommonUriTb4b4b4.Te6edf3parseTb4b4b4(Ta5d6ff"Ta5d6ffcontent://testTa5d6ff"Tb4b4b4)
Te6edf3vmTb4b4b4.Te6edf3savePowerMetricsCSVTb4b4b4(Te6edf3uriTb4b4b4, Te6edf3listOfTb4b4b4(Te6edf3testTelemetryTb4b4b4)Tb4b4b4)
Te6edf3runCurrentTb4b4b4(Tb4b4b4)

Te6edf3verifySuspend Tb4b4b4{ Te6edf3fileServiceTb4b4b4.Te6edf3writeTb4b4b4(Te6edf3uriTb4b4b4, Te6edf3anyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4}

Tff7b72val Te6edf3csvOutput Tff7b72= Te6edf3bufferTb4b4b4.Te6edf3readUtf8Tb4b4b4(Tb4b4b4)
Te6edf3assertTrueTb4b4b4(
Te6edf3csvOutputTb4b4b4.Te6edf3startsWithTb4b4b4(
Ta5d6ff"Ta5d6ff\"Ta5d6ffdateTa5d6ff\"Ta5d6ff,Ta5d6ff\"Ta5d6fftimeTa5d6ff\"Ta5d6ff,Ta5d6ff\"Ta5d6ffch1VoltageTa5d6ff\"Ta5d6ff,Ta5d6ff\"Ta5d6ffch1CurrentTa5d6ff\"Ta5d6ff,Ta5d6ff\"Ta5d6ffch2VoltageTa5d6ff\"Ta5d6ff,Ta5d6ff\"Ta5d6ffch2CurrentTa5d6ff\"Ta5d6ff,Ta5d6ff\"Ta5d6ffch3VoltageTa5d6ff\"Ta5d6ff,Ta5d6ff\"Ta5d6ffch3CurrentTa5d6ff\"Ta5d6ff"Tb4b4b4,
Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Te6edf3assertTrueTb4b4b4(Te6edf3csvOutputTb4b4b4.Te6edf3containsTb4b4b4(Ta5d6ff"Ta5d6ff\"Ta5d6ff3.3Ta5d6ff\"Ta5d6ff,Ta5d6ff\"Ta5d6ff0.1Ta5d6ff\"Ta5d6ff,Ta5d6ff\"Ta5d6ff5.0Ta5d6ff\"Ta5d6ff,Ta5d6ff\"Ta5d6ff0.2Ta5d6ff\"Ta5d6ff,Ta5d6ff\"Ta5d6ff12.0Ta5d6ff\"Ta5d6ff,Ta5d6ff\"Ta5d6ff0.3Ta5d6ff\"Ta5d6ff"Tb4b4b4)Tb4b4b4)

Te6edf3cancelAndIgnoreRemainingEventsTb4b4b4(Tb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}

Served by rngit 1.5.0 - Generated in 0.12s